package ece1779.servlets;

import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.sql.DataSource;

import org.apache.commons.fileupload.*;
import org.apache.commons.fileupload.disk.*;
import org.apache.commons.fileupload.servlet.*;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.Bucket;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;

import org.im4java.core.*;


public class ViewImages extends HttpServlet {
	public void doGet( HttpServletRequest request, HttpServletResponse response )
	throws IOException, ServletException {
		
		Connection con = null;
		try{
			PrintWriter out = response.getWriter();

		    HttpSession session = request.getSession();		   
		    session.setAttribute("addedImage", new String ("false") );
			
	        response.setContentType("text/html");
	        
	        out.println("<html><head></head/><title>Your Images</title>");
	        out.println("<body>");
	        out.println("Hello?");
	        out.println("</body></html>");
	        
	        
            // In real life, you should get these values from a shopping cart
            //int userId = 1;//get from db
            
		    // Get DB connection from pool
		    DataSource dbcp = (DataSource)this.getServletContext().getAttribute("dbpool");
		    con = dbcp.getConnection();
						 
		    String userId = session.getAttribute("userIdddd").toString();
			//String userId =  this.getServletContext().getAttribute("userIdddd").toString(); //request.getAttribute("userId").toString();
			
			//Get list of images from DB
			String sql = "SELECT * FROM images WHERE userId=" + userId + ";";
		    Statement stmt = con.createStatement();
		    ResultSet rs = stmt.executeQuery( sql );
		    List<String> images = new ArrayList<String>();
		    while( rs.next() )
		    {
		    	images.add(rs.getString("key1"));
		    }
		    //this.getServletContext().setAttribute("userimages", images);
		    request.setAttribute("userimages", images );
		    request.getRequestDispatcher("/jsp/ViewImages.jsp").forward(request, response);//.forward(request, response);
		}
    	catch(Exception ex) {
    		  response.getWriter().println(ex.getMessage());
              //getServletContext().log(ex.getMessage());  
    	}    	
    	finally {
    		try {
    			con.close();
    		} 
    		catch (Exception e) {
                getServletContext().log(e.getMessage());  
    		}
    	}  
		
		
		
	}
	
	
	
	
	
	
	
	
    public void doPost(HttpServletRequest request, HttpServletResponse response)
	throws IOException, ServletException {
        try {

        	// Create a factory for disk-based file items
        	FileItemFactory factory = new DiskFileItemFactory();

        	// Create a new file upload handler
        	ServletFileUpload upload = new ServletFileUpload(factory);

        	// Parse the request
        	List /* FileItem */ items = upload.parseRequest(request);
        	
        	
        	// User ID
        	FileItem item1 = (FileItem)items.get(0);
        	
        	String name = item1.getFieldName();
        	String value = item1.getString();
        	
        	//Uploaded File
            FileItem theFile = (FileItem)items.get(1);


            // filename on the client
            String fileName = theFile.getName();
   
            // get root directory of web application
            String path = this.getServletContext().getRealPath("/");        

            
            String key1 = "MyObjectKey_" + UUID.randomUUID();
            String key2 = "MyObjectKey_" + UUID.randomUUID();
            String key3 = "MyObjectkey_" + UUID.randomUUID();
            String key4 = "MyObjectkey_" + UUID.randomUUID();
            
            String name1 = path+key1;//original
            String name2 = path+key2;//xform1
            String name3 = path+key3;//xform2
            String name4 = path+key4;//xform3
            
            // store file in server
            File file1 = new File(name1); 
            theFile.write(file1);//this writes to disk. can we make it write to S3 directly?

            // Use imagemagik to transform image
            IMOperation op = new IMOperation();
            op.addImage();
            op.flip();
            op.addImage();
            
            ConvertCmd cmd = new ConvertCmd();
            cmd.run(op, name1,name2);

            File file2 = new File(name2);
            
            IMOperation op2 = new IMOperation();
            op2.addImage();
            op2.gaussianBlur(100.0, 0.845123);//does not work?
            op2.rotate(270.0);
            op2.addImage();
            cmd.run(op2, name1, name3);
            
            File file3 = new File(name3);
            
            IMOperation op3 = new IMOperation();
            op3.addImage();
            op3.rotate(90.0);
            op3.addImage();
            cmd.run(op3, name1, name4);           
 
            File file4 = new File(name4);
            
            PrintWriter out = response.getWriter();

            s3SaveFile(file1, key1, out);
        	s3SaveFile(file2, key2, out);
        	s3SaveFile(file3, key3, out);
        	s3SaveFile(file4, key4, out);
        	
        	updateDatabase(key1,key2,key3, key4,out);

        	

        	response.setContentType("text/html");
            
            out.write("<html><head><title>Sample Image Upload</title></head>");
            out.write("<body>");
        	
            out.write("<img src='https://s3.amazonaws.com/ece1779kfc/" + key1 + "' />");
            out.write("<img src='https://s3.amazonaws.com/ece1779kfc/" + key2 + "' />");
            out.write("<img src='https://s3.amazonaws.com/ece1779kfc/" + key3 + "' />");
            out.write("<img src='https://s3.amazonaws.com/ece1779kfc/" + key4 + "' />");
            
            
            out.write("</body></html>");
             
	}
	catch (Exception ex) {
	    throw new ServletException (ex);
	}
	
    }
    
    public void updateDatabase(String key1, String key2, String key3, String key4, PrintWriter out) {
    	Connection con = null;
    	try{ 
            // In real life, you should get these values from a shopping cart
            int userId = 1;//get from db
            
		    // Get DB connection from pool
		    DataSource dbcp = (DataSource)this.getServletContext().getAttribute("dbpool");
		    con = dbcp.getConnection();
	
		    // Execute SQL query
		    Statement stmt = con.createStatement();
		    
		    String insert = "INSERT INTO images (userId, key1, key2, key3, key4) VALUES (?,?,?,?,?);";
		    
		    PreparedStatement ps = con.prepareStatement(insert);
		    // image id auto increments when inserting
		    ps.setInt(1, userId);
		    ps.setString(2, key1);
		    ps.setString(3, key2);
		    ps.setString(4, key3);
		    ps.setString(5, key4);
		    ps.executeUpdate();
		    
		    //String sql = "INSERT INTO images (userid, key1, key2, key3, key4) VALUES (" 
		    //	+ userId + ",' " + key1 + "',' " + key2 + "',' " + key3 + "',' " + key4 + "');";
		    
            //String    sql = "insert into images (id, userid, key1, key2) "+
            //          "value(" + userid + ",'" + key1 + ",'"+ key2 + "')";
            //stmt.executeUpdate(sql);
        }
    	catch(Exception ex) {
    		  //out.println(ex.getMessage());
              getServletContext().log(ex.getMessage());  
    	}    	
    	finally {
    		try {
    		con.close();
    		} 
    		catch (Exception e) {
                getServletContext().log(e.getMessage());  
    		}
    	}  

    }   
     
    
    public void s3SaveFile(File file, String key, PrintWriter out) throws IOException {

    	BasicAWSCredentials awsCredentials = (BasicAWSCredentials)this.getServletContext().getAttribute("AWSCredentials");

    	AmazonS3 s3 = new AmazonS3Client(awsCredentials);
        
        String bucketName = "ece1779kfc";
 


        try {
            s3.putObject(new PutObjectRequest(bucketName, key, file));
            
            s3.setObjectAcl(bucketName, key, CannedAccessControlList.PublicRead);

        } catch (AmazonServiceException ase) {
            out.println("Caught an AmazonServiceException, which means your request made it "
                    + "to Amazon S3, but was rejected with an error response for some reason.");
            out.println("\nError Message:    " + ase.getMessage());
            out.println("\nHTTP Status Code: " + ase.getStatusCode());
            out.println("\nAWS Error Code:   " + ase.getErrorCode());
            out.println("\nError Type:       " + ase.getErrorType());
            out.println("\nRequest ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            out.println("Caught an AmazonClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with S3, "
                    + "such as not being able to access the network.");
            out.println("Error Message: " + ace.getMessage());
        }
    }
    
    
}